package com.mqb.handler.netty;

import com.alibaba.fastjson.JSON;
import com.mqb.*;
import com.mqb.session.UserSession;
import com.mqb.util.ByteBufUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ChannelHandler.Sharable
public class RequestMsgInboundHandler extends ChannelInboundHandlerAdapter {
    private static final Logger log = LoggerFactory.getLogger(RequestMsgInboundHandler.class);

    // 到这里时已经经过了 LoginInboundHandler 的过滤，所以这里的 msg 就是 RequestMsg
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        RequestMsg requestMsg = (RequestMsg) msg;

        log.info("收到消息，从 [{}] 发送给 [{}]，内容为[{}]", requestMsg.getSendId(), requestMsg.getRecId(), requestMsg.getContent());

        // 1. 收到消息首先回复客户端收到
        AckMsg ackToSender = new AckMsg(requestMsg.getId(), requestMsg.getSendId(), MsgConstant.SERVER, Result.success());
        ctx.channel().writeAndFlush(ByteBufUtil.transferWithHead(ackToSender));

        // 2. 判断消息接受者是否在线
        String recId = requestMsg.getRecId();
        Channel recChannel = UserSession.getChannelByUserId(recId);
        if (recChannel == null) {

            // 假装持久化完成

            // 伪造最终回复给消息发送者

            NotifyMsg notifyMsg = new NotifyMsg(requestMsg.getId(), requestMsg.getRecId(), requestMsg.getDateTime(), null);
            ctx.channel().writeAndFlush(ByteBufUtil.transferWithHead(notifyMsg));

        } else {
            // 在线
            if (!requestMsg.isReceivedFlag()) {
                // 继续将消息转发给接收者
                DeliverMsg deliverMsg = new DeliverMsg(requestMsg.getId(), requestMsg.getRecId(), requestMsg.getSendId(), JSON.toJSONString(requestMsg));
                recChannel.writeAndFlush(ByteBufUtil.transferWithHead(deliverMsg));
            } else {
                NotifyMsg notifyMsg = new NotifyMsg(requestMsg.getId(), requestMsg.getRecId(), requestMsg.getDateTime(), null);
                recChannel.writeAndFlush(ByteBufUtil.transferWithHead(notifyMsg));
            }
        }
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        String userIdByChannel = UserSession.getUserIdByChannel(ctx.channel());
        UserSession.remove(userIdByChannel);
        log.info("用户 [{}] 下线了...{}", userIdByChannel, ctx.channel());
        super.channelUnregistered(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("{} {}exceptionCaught", ctx.channel(), cause);
        //super.exceptionCaught(ctx, cause);
    }
}
